package com.imooc.user.controller;

import com.imooc.dto.UserDTO;
import com.imooc.thrift.user.UserInfo;
import com.imooc.user.response.LoginResponse;
import com.imooc.user.thrift.ServiceProvider;
import org.apache.thrift.TException;
import org.apache.tomcat.util.buf.HexUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;


/**
 * @Auther: zhaozeyang
 * @Date: 2018/8/19 19:28
 * @Description:
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private ServiceProvider serviceProvider;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    private final static String TOKEN_PREFIX = "token:";

    @PostMapping("/login")
    public LoginResponse login(@RequestParam("username") String username,
                               @RequestParam("password") String password) throws Exception {

        UserInfo userInfo = serviceProvider.getUserService().getUserByName(username);
        if (!userInfo.getPassword().equals(md5(password))) {
            System.out.println(md5(password));
            throw new RuntimeException();
        }
        String token = getToken();
        stringRedisTemplate.opsForValue().set(TOKEN_PREFIX.concat(":").concat(token), String.valueOf(userInfo.getUsername()));
        return new LoginResponse(token);
    }

    @GetMapping("/tologin")
    public String toLogin() {
        return "please to login";
    }

    @PostMapping("/register")
    public UserDTO register(@Valid @RequestBody UserDTO userDTO) throws TException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, UnsupportedEncodingException, NoSuchAlgorithmException {
        UserInfo userInfo = new UserInfo();
        BeanUtils.copyProperties(userDTO, userInfo);
        userInfo.setPassword(md5(userInfo.getPassword()));
        String code = null;
        if (!StringUtils.isEmpty(userDTO.getEmail())) {
            code = stringRedisTemplate.opsForValue().get(userDTO.getEmail());
        } else if (!StringUtils.isEmpty(userDTO.getMobile())) {
            code = stringRedisTemplate.opsForValue().get(userDTO.getMobile());
        }
        if (code == null || !code.equals(userDTO.getVerifyCode())) {
            throw new RuntimeException();
        }
        serviceProvider.getUserService().regiserUser(userInfo);
        return userDTO;
    }

    @PostMapping(value = "/auth")
    public UserDTO authentication(@RequestHeader("token") String token) throws Exception {
        String username = stringRedisTemplate.opsForValue().get(TOKEN_PREFIX.concat(":").concat(token));
        if (StringUtils.isEmpty(username)) {
            return null;
        }
        UserDTO userDTO = new UserDTO();
        UserInfo userInfo= serviceProvider.getUserService().getUserByName(username);
        BeanUtils.copyProperties(userInfo, userDTO);
        return userDTO;

    }

    @GetMapping("/code")
    public String sendVerifyCode(@RequestParam(value = "mobile", required = false) String mobile,
                                 @RequestParam(value = "email", required = false) String email) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, TException {
        String message = "Verify code is:";
        String code = getToken();
        if (!StringUtils.isEmpty(mobile)) {
            serviceProvider.getMessageService().sendMobileMessage(mobile, message.concat(code));
            stringRedisTemplate.opsForValue().set(mobile, code);
        } else if (!StringUtils.isEmpty(email)) {
            serviceProvider.getMessageService().sendEmailMessage(email, message.concat(code));
            stringRedisTemplate.opsForValue().set(email, code);
        } else {
            return "please give me five";
        }
        return "success";
    }

    private String getToken() {
        return UUID.randomUUID().toString();
    }

    private String md5(String password) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        MessageDigest md5 = MessageDigest.getInstance("md5");
        byte[] md5Bytes = md5.digest(password.getBytes("utf-8"));
        return HexUtils.toHexString(md5Bytes);
    }
}
